/*
 * File: vfsdriver.c
 *
 * Description: This is a driver program for testing your VFS system using an interaction script as input
 * You need to make additional calls to your respective functions as noted in the comments below
 * Make sure the output you display is exactly as per the given specifications for you. Do NOT print
 * any extra output (like debug messages) in the final version of your driver program. You can use this driver program
 * in a in incremental manner as you keep implementing one operator after another. For operators not yet implemented,
 * you can leave the output as given ("TO_BE_DONE"). So you can use this program as your "main" program for testing purposes.
 *
 * DO NOT write the full code for operators in the driver program! You must only CALL your functions from here.
 *
 * Usage: vfsdriver <scriptfilename>
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"../include/main.h"
#include"../include/create_vfs.h"
#include"../include/mount_vfs.h"
#include"../include/unmount_vfs.h"
#include"../include/makedir.h"
#include"../include/create_file.h"
#include"../include/narrtree.h"
#include"../include/hash.h"
#include"../include/constants.h"
#include"../include/movedir.h"
#include"../include/deldir.h"
#include"../include/movefile.h"
#include"../include/listdir.h"
#include"../include/exportfile.h"
#include"../include/search_file.h"
#include"../include/updatefile.h"
#include"../include/removefile.h"
#include"../include/listfile.h"
#include"../include/copyfile.h"
#include"../include/vfs_errorcodes.h"

#define BUFSIZE 200
#define CMDSIZE 30
#define PARSIZE 100

void createvfs ( char *P1, int P2 );
void mount_vfs ( char *P1 );
void unmount_vfs ( char *P1 );
void make_dir ( char *P1, char *P2 );
void deletedir ( char *P1 );
void move_dir ( char *P1, char *P2 );
void listdir ( char *P1, int P2, char *P3 );
void add_file ( char *P1, char *P2, char *P3 );
void listfile ( char *P1, char *P2 );
void updatefile ( char *P1, char *P2 );
void removefile ( char *P1 );
void move_file ( char *P1, char *P2 );
void copyfile ( char *P1, char *P2 );
void exportfile ( char *P1, char *P2 );
void searchfile ( char *P1, char *P2 );

void processcommand( char *command, char *P1, char *P2, char *P3 );

int main( int argc, char *argv[] )
{
	FILE *scriptfp;
	mounted=0;
	char linebuffer[BUFSIZE];
	char command[CMDSIZE], par1[PARSIZE], par2[PARSIZE], par3[PARSIZE];
	char *token;
	schflag=0;
	if( argc != 2 ){
		fprintf(stderr,"Usage: vfsdriver <scriptfile>\n");
		return(1);
	}

	if( (scriptfp=fopen(argv[1],"r")) == NULL ){
		fprintf(stderr,"Unable to open script file: %s\n", argv[1]);
		return(2);
	}

	while( fgets(linebuffer, sizeof(linebuffer), scriptfp) != NULL ){
		/* This output is for debugging... do not uncomment in final version */
		/*
		printf("==================================================\n");
		printf("Processing: %s", linebuffer);
		printf("==================================================\n");
		*/

		/* Remove the extra newline character in the end of line */
		linebuffer[ strlen(linebuffer)-1 ] = '\0';
		
		/* Get the command and the parameters using tokenizer */
		strcpy( command, (token = strtok(linebuffer, " ")) == NULL ? "" : token );
		
		strcpy( par1, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par2, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par3, (token = strtok(NULL, " ")) == NULL ? "" : token );
		//printf("Command:%s:p1:%s:p2:%s:p3:%s\n",command, par1, par2, par3);
		strcpy(glb_command,command);
		processcommand( command, par1, par2, par3 );
	}
}

void processcommand( char *command, char *P1, char *P2, char *P3 )
{
	if( strcmp(command, "createvfs") == 0 )
	{
		int size = atoi(P2);
		//printf("%s\n",P1);
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_CREATE_00);
		else
			createvfs (P1,size);
	}
	else if( strcmp(command, "mountvfs") == 0 )
	{
		if(strlen(P1)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOUNT_00);
		else
			mount_vfs (P1);
	}
	else if( strcmp(command, "unmountvfs") == 0 )
	{
		if(strlen(P1)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_UNMOUNT_00);
		else
			unmount_vfs (P1);
	}
	else if( strcmp(command, "makedir") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MAKEDIR_00);
		else
			make_dir (P1,P2);
	}
	else if( strcmp(command, "deletedir") == 0 )
	{
		if(strlen(P1)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_DELETEDIR_00);
		else
			deletedir (P1);
	}
	else if( strcmp(command, "movedir") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEDIR_00);
		else
			move_dir (P1,P2);
	}
	else if( strcmp(command, "listdir") == 0 ){
		int flag = atoi(P2);
		if(strlen(P1)==0 || strlen(P2)==0 || strlen(P3)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_LISTDIR_00);
		else if(flag != 0 && flag != 1)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_LISTDIR_02);			
		else
			listdir (P1,flag,P3);
	}
	else if( strcmp(command, "addfile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0 || strlen(P3)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_ADDFILE_00);
		else
			add_file (P1,P2,P3);
	}
	else if( strcmp(command, "listfile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_LISTFILE_00);
		else
			listfile (P1,P2);
	}
	else if( strcmp(command, "updatefile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_UPDATEFILE_00);
		else
			updatefile (P1,P2);
	}
	else if( strcmp(command, "removefile") == 0 )
	{
		if(strlen(P1)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_REMOVEFILE_00);
		else
			removefile (P1);
	}
	else if( strcmp(command, "movefile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_MOVEFILE_00);
		else
			move_file (P1,P2);
	}
	else if( strcmp(command, "copyfile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_00);
		else
			copyfile (P1,P2);
	}
	else if( strcmp(command, "exportfile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_EXPORTFILE_00);
		else
			exportfile (P1,P2);
	}
	else if( strcmp(command, "searchfile") == 0 )
	{
		if(strlen(P1)==0 || strlen(P2)==0)
			printf("%s_FAILURE %s\n",glb_command,ERR_VFS_SEARCHFILE_00);
		else
			searchfile (P1,P2);
	}
	else
		printf("Ignoring invalid command %s\n", command);
}

void createvfs ( char *P1, int P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("createvfs_TO_BE_DONE\n");
	char str[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str[i]=P1[i++];
	str[i]='\0';
	create_vfs(str,P2);
}

void mount_vfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("mountvfs_TO_BE_DONE\n");
	char str[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str[i]=P1[i++];
	str[i]='\0';
	mountvfs(str);
}

void unmount_vfs ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("unmountvfs_TO_BE_DONE\n");
	char str[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str[i]=P1[i++];
	str[i]='\0';
	unmountvfs(str);
}

void make_dir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("makedir_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	makedir(str1,str2);
}

void deletedir ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("deletedir_TO_BE_DONE\n");
	char str[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str[i]=P1[i++];
	str[i]='\0';
	deldir(str);
}

void move_dir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("movedir_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	movedir(str1,str2);
}

void listdir ( char *P1, int P2, char *P3 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("listdir_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P3[i]!='\0')
		str2[i]=P3[i++];
	str2[i]='\0';
	listdirty(str1,P2,str2);
}

void add_file ( char *P1, char *P2, char *P3 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("addfile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME],str3[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	i=0;
	while(P3[i]!='\0')
		str3[i]=P3[i++];
	str3[i]='\0';
	addfile(str1,str2,str3);
}

void listfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("listfile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	list_file(str1,str2);
}

void updatefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("updatefile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	update(str1,str2);
}

void removefile ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("removefile_TO_BE_DONE\n");
	char str1[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	remove_file(str1);
}

void move_file ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("movefile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	movefile(str1,str2);
}

void copyfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("copyfile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	copy_file(str1,str2);
}

void exportfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("exportfile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	export_file(str1,str2);
}

void searchfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("searchfile_TO_BE_DONE\n");
	char str1[MAX_NAME],str2[MAX_NAME];
	int i=0;
	while(P1[i]!='\0')
		str1[i]=P1[i++];
	str1[i]='\0';
	i=0;
	while(P2[i]!='\0')
		str2[i]=P2[i++];
	str2[i]='\0';
	search_file(str1,str2);	
}
